package com.iplant.base.utils.annotation.field;

import com.alibaba.fastjson.JSON;
import com.iplant.base.po.enums.DBEnumType;
import com.iplant.base.utils.annotation.DBBaseValue;
import com.iplant.base.utils.general.StringUtils;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;

/**
 * @author xiuto
 */
public class DBFieldValue extends DBBaseValue {
    /**
     * 字段值
     */
    public Object value = "";


    public boolean IsJson = false;

    /**
     * 获取字段数据，默认将数组 list 转成String
     *
     * @return Object
     */
    public Object getValue() {
        if (value == null)
            return "";
        if (this.value instanceof Collection) {
            if(this.IsJson){
                return StringUtils.toJSONString(this.value);
            }else{
                return StringUtils.JoinCollection(",", (Collection) this.value);
            }
        } else if (this.value instanceof Map) {
            return StringUtils.toJSONString((Map) this.value);
        } else if (this.value.getClass().isArray()) {
            if(this.IsJson){
                return StringUtils.toJSONString(this.value);
            }else{
                return StringUtils.JoinArray(",", this.value);
            }
        }
        return value;
    }

    public void setValue(Map<String, Object> wReader) {
        if (!wReader.containsKey(viewName))
            return;
        if(wReader.get(viewName)==null)
            return;
        switch (TypeName.toLowerCase()) {

            case "int":
            case "integer":
            case "long":
            case "char":
            case "character":
            case "double":
            case "float":
            case "short":
            case "byte":
            case "string":
            case "calendar":
            case "date":
                break;
            case "boolean":
                wReader.put(viewName, StringUtils.parseBoolean(wReader.get(viewName)));
                break;
            default:
                if (TypeName.toLowerCase().contains("list") || TypeName.toLowerCase().contains("array")) {
                    if (POField == null) {
                        wReader.put(viewName, StringUtils.splitList(wReader.get(viewName).toString(), ","));
                    } else {
                        if (POField.getGenericType().getTypeName().contains("Integer")
                                || POField.getGenericType().getTypeName().contains("Long")
                                || POField.getGenericType().getTypeName().contains("Short")
                                || POField.getGenericType().getTypeName().contains("byte")) {
                            wReader.put(viewName, StringUtils.parseIntList(wReader.get(viewName).toString(), ","));
                        } else if (POField.getGenericType().getTypeName().contains("Double")
                                || POField.getGenericType().getTypeName().contains("Float")) {
                            wReader.put(viewName, StringUtils.parseDoubleList(wReader.get(viewName).toString(), ","));
                        } else {
                            if (this.IsJson) {
                                wReader.put(viewName, JSON.parseArray(StringUtils.parseString(wReader.get(viewName)), Map.class));
                            } else {
                                wReader.put(viewName, StringUtils.splitList(wReader.get(viewName).toString(), ","));
                            }
                        }
                    }
                } else if (TypeName.toLowerCase().contains("map")) {
                    wReader.put(viewName, JSON.parseObject(wReader.get(viewName).toString(), Map.class));
                }
                break;
        }
    }


    /**
     * 是否支持插入
     */
    public boolean Insert = true;

    /**
     * 是否支持更新
     */
    public boolean Update = true;

    /**
     * 字段是否有效
     */
    public boolean exist = true;

    /**
     * 是否不能为空
     */
    public boolean notNull = true;

    public boolean ValueAuto = false;
    public boolean CheckValue = false;

    /**
     * 字符串的长度  >0
     */
    public int length = 255;

    /**
     * 表中列的备注
     */
    public String Description = "";

    /**
     * 表中列的默认值
     */
    public String DefaultValue = "";


    /**
     * 字段的数据库类型
     */

    public String TypeName = "String";


    public Field POField;


    public DBFieldValue(String wTableAsName, DBField wDBField, Field wField) {
        this.name = wDBField.name();
        this.viewName = wField.getName();
        this.Insert = wDBField.Insert();
        this.ValueAuto = wDBField.ValueAuto();
        this.Update = wDBField.Update();
        this.exist = wDBField.exist();
        this.tableAsName = wTableAsName;
        this.notNull = wDBField.notNull();
        this.CheckValue = wDBField.CheckValue();
        this.length = wDBField.length();
        this.Description = wDBField.Description();
        this.DefaultValue = wDBField.DefaultValue();
        this.TypeName = wField.getType().getSimpleName();
        this.IsJson = wDBField.isJson();
        if (StringUtils.isEmpty(this.name)) {
            this.name = this.viewName;
        }
        if (StringUtils.isNotEmpty(this.DefaultValue)&&this.DefaultValue.indexOf("'")<0) {
            this.DefaultValue ="'"+ this.DefaultValue+"'";
        }
        POField = wField;

    }


    public DBFieldValue(String wTableAsName, DBField wDBField, Field wField, Object wValue) {
        this.name = wDBField.name();
        this.viewName = wField.getName();
        this.Insert = wDBField.Insert();
        this.ValueAuto = wDBField.ValueAuto();
        this.Update = wDBField.Update();
        this.exist = wDBField.exist();
        this.tableAsName = wTableAsName;
        this.notNull = wDBField.notNull();
        this.CheckValue = wDBField.CheckValue();
        this.length = wDBField.length();
        this.Description = wDBField.Description();
        this.DefaultValue = wDBField.DefaultValue();
        this.TypeName = wField.getType().getSimpleName();
        this.IsJson = wDBField.isJson();
        if (StringUtils.isEmpty(this.name)) {
            this.name = this.viewName;
        }
        if (StringUtils.isNotEmpty(this.DefaultValue)&&this.DefaultValue.indexOf("'")<0) {
            this.DefaultValue ="'"+ this.DefaultValue+"'";
        }
        POField = wField;
        this.value = wValue;
    }

    public String getDefaultValue(DBEnumType wSQLTypeField) {
        String wResult = "''";
        switch (wSQLTypeField) {

            case Default:
            case MySQL:
                wResult = this.getMysqlDefaultValue();
                break;
            case SQLServer:
                wResult = this.getSqlServerDefaultValue();
                break;
            case Oracle:
                break;
            case Access:
                break;
        }
        return wResult;
    }

    private String getMysqlDefaultValue() {
        String wResult = DefaultValue;
        if (StringUtils.isNotEmpty(DefaultValue)) {
            return DefaultValue;
        }
        switch (this.TypeName.toLowerCase()) {
            case "int":
            case "integer":
            case "long":
            case "double":
            case "float":
            case "short":
            case "byte":
                wResult = "'0'";
                break;
            case "boolean":
                wResult = "b'0'";
                break;
            case "calendar":
            case "date":
                wResult = "'2000-01-01'";
                break;
            default:
                wResult = "''";
                break;
        }
        return wResult;
    }

    private String getSqlServerDefaultValue() {
        String wResult = DefaultValue;
        if (StringUtils.isNotEmpty(DefaultValue)) {
            return DefaultValue;
        }
        switch (this.TypeName.toLowerCase()) {
            case "int":
            case "integer":
            case "long":
            case "double":
            case "float":
            case "short":
            case "byte":
            case "boolean":
                wResult = "'0'";
                break;
            case "calendar":
            case "date":
                wResult = "'2000-01-01'";
                break;
            default:
                wResult = "''";
                break;
        }
        return wResult;
    }
}